package com.aviator.detective.execute.execute;

import com.aviator.detective.model.variable.ExpressVariable;
import com.aviator.detective.script.aviator.AviatorCode;
import com.aviator.detective.script.aviator.AviatorResult;
import com.aviator.detective.script.aviator.DefaultAviatorScriptExecute;
import org.apache.commons.lang3.StringUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class RuleExecute extends DefaultAviatorScriptExecute {

    private ExecuteResultContext context;

    private BaseExecutePostProcessor ruleExecutePostProcessor;

    public RuleExecute(ExecuteResultContext context){
        super(context.getParamContext());
        this.context = context;
    }

    public ExecuteResultContext executeRule(){
        String script = context.getRule().getScript();
        List<ExpressVariable> variableList =context.getRule().getVariableList();
        if (StringUtils.isBlank(script)){
            //TODO throw Exception
        }
        ruleExecutePostProcessor.beforeRuleExecute(context);
        Boolean flag = doExecuteRule(script);
        if (variableList != null && variableList.size() != 0){
            doExecuteVariables(variableList);
        }
        ruleExecutePostProcessor.afterRuleExecute(context);
        if (flag){
            context.setExecResult(true);
        }
        return context;
    }

    public Boolean doExecuteRule(String script){
        AviatorResult<Boolean> aviatorResult = executeBoolean(script);
        if(aviatorResult.getCode().equals(AviatorCode.SUCCESS)){
            return aviatorResult.getT();
        }else{
            context.setErrCode(aviatorResult.getCode().name());
            context.setErrMessage(aviatorResult.getMsg());
        }
        return false;
    }

    public Map<String,Object> doExecuteVariables(List<ExpressVariable>  variables){
        Map<String,Object> map = new HashMap<>();
        for (ExpressVariable variable : variables) {
            AviatorResult result = doExecuteVariable(variable);
            map.put(variable.getId(),result);
        }
        return map;
    }

    private AviatorResult doExecuteVariable(ExpressVariable variable) {
        return execute(variable.getScript(),variable.getVariableType());
    }

}
